/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.cspimp.esrz.service.impl;

import me.zhengjie.modules.cspimp.esrz.domain.RiskZoningManage;
import me.zhengjie.modules.system.domain.AreaManage;
import me.zhengjie.modules.system.domain.Dept;
import me.zhengjie.modules.system.domain.User;
import me.zhengjie.modules.system.repository.AreaManageRepository;
import me.zhengjie.modules.system.repository.DeptRepository;
import me.zhengjie.modules.system.repository.UserRepository;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.cspimp.esrz.repository.RiskZoningManageRepository;
import me.zhengjie.modules.cspimp.esrz.service.RiskZoningManageService;
import me.zhengjie.modules.cspimp.esrz.service.dto.RiskZoningManageDto;
import me.zhengjie.modules.cspimp.esrz.service.dto.RiskZoningManageQueryCriteria;
import me.zhengjie.modules.cspimp.esrz.service.mapstruct.RiskZoningManageMapper;
import me.zhengjie.utils.enums.RiskLevelEnum;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;

/**
* @website https://docs.auauz.net
* @description 服务实现
* @author 黄星星
* @date 2020-05-30
**/
@Service
@RequiredArgsConstructor
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class RiskZoningManageServiceImpl implements RiskZoningManageService {

    private final RiskZoningManageRepository riskZoningManageRepository;
    private final RiskZoningManageMapper riskZoningManageMapper;
    private final DeptRepository deptRepository;
    private final UserRepository userRepository;
    private final AreaManageRepository areaManageRepository;

    @Override
    public Map<String,Object> queryAll(RiskZoningManageQueryCriteria criteria, Pageable pageable){
        Page<RiskZoningManage> page = riskZoningManageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(riskZoningManageMapper::toDto));
    }

    @Override
    public List<RiskZoningManageDto> queryAll(RiskZoningManageQueryCriteria criteria){
        return riskZoningManageMapper.toDto(riskZoningManageRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    public RiskZoningManageDto findById(Long id) {
        RiskZoningManage riskZoningManage = riskZoningManageRepository.findById(id).orElseGet(RiskZoningManage::new);
        ValidationUtil.isNull(riskZoningManage.getId(),"RiskZoningManage","id",id);
        return riskZoningManageMapper.toDto(riskZoningManage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public RiskZoningManageDto create(RiskZoningManage resources) {
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        resources.setId(snowflake.nextId());
        Long depId = resources.getDepId();
        String depName = resources.getDepName();
        if(StringUtils.isEmpty(depName) && null != depId){
            Optional<Dept> deptOptional = deptRepository.findById(depId);
            if(null != deptOptional){
                Dept dept = deptOptional.get();
                if(null != dept){
                    resources.setDepName(dept.getName());
                }
            }
        }

        Long depManagerId = resources.getDepManagerId();
        String depManageName = resources.getDepManageName();
        if(StringUtils.isEmpty(depManageName) && null != depManagerId){
            Optional<User> userOptional = userRepository.findById(depManagerId);
            if(null != userOptional){
                User user = userOptional.get();
                if(null != user){
                    resources.setDepManageName(user.getUsername());
                }
            }
        }

        Long relAreaId = resources.getRelAreaId();
        String relAreaName = resources.getRelAreaName();
        if(StringUtils.isEmpty(relAreaName) && null != relAreaId){
            Optional<AreaManage> areaManageOptional = areaManageRepository.findById(relAreaId);
            if(null != areaManageOptional){
                AreaManage areaManage = areaManageOptional.get();
                if(null != areaManage){
                    resources.setRelAreaName(areaManage.getAreaName());
                }
            }
        }

        Long riskLevelId = resources.getRiskLevelId();
        String riskLevelName = resources.getRiskLevelName();
        String riskLevelCode = resources.getRiskLevelCode();

        if(null != riskLevelId && (StringUtils.isEmpty(riskLevelCode) || StringUtils.isEmpty(riskLevelName))){
            RiskLevelEnum riskLevelEnum = RiskLevelEnum.find(riskLevelId);
            if(null != riskLevelEnum){
                resources.setRiskLevelCode(riskLevelEnum.getCode());
                resources.setRiskLevelName(riskLevelEnum.getName());
            }
        }
        RiskZoningManage riskZoningManage = riskZoningManageRepository.save(resources);
        return riskZoningManageMapper.toDto(riskZoningManage);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(RiskZoningManage resources) {
        RiskZoningManage riskZoningManage = riskZoningManageRepository.findById(resources.getId()).orElseGet(RiskZoningManage::new);
        ValidationUtil.isNull( riskZoningManage.getId(),"RiskZoningManage","id",resources.getId());
        riskZoningManage.copy(resources);
        Long depId = resources.getDepId();
        String depName = resources.getDepName();
        if(StringUtils.isEmpty(depName) && null != depId){
            Optional<Dept> deptOptional = deptRepository.findById(depId);
            if(null != deptOptional){
                Dept dept = deptOptional.get();
                if(null != dept){
                    resources.setDepName(dept.getName());
                }
            }
        }

        Long depManagerId = resources.getDepManagerId();
        String depManageName = resources.getDepManageName();
        if(StringUtils.isEmpty(depManageName) && null != depManagerId){
            Optional<User> userOptional = userRepository.findById(depManagerId);
            if(null != userOptional){
                User user = userOptional.get();
                if(null != user){
                    resources.setDepManageName(user.getUsername());
                }
            }
        }

        Long relAreaId = resources.getRelAreaId();
        String relAreaName = resources.getRelAreaName();
        if(StringUtils.isEmpty(relAreaName) && null != relAreaId){
            Optional<AreaManage> areaManageOptional = areaManageRepository.findById(relAreaId);
            if(null != areaManageOptional){
                AreaManage areaManage = areaManageOptional.get();
                if(null != areaManage){
                    resources.setRelAreaName(areaManage.getAreaName());
                }
            }
        }

        Long riskLevelId = resources.getRiskLevelId();
        String riskLevelName = resources.getRiskLevelName();
        String riskLevelCode = resources.getRiskLevelCode();

        if(null != riskLevelId && (StringUtils.isEmpty(riskLevelCode) || StringUtils.isEmpty(riskLevelName))){
            RiskLevelEnum riskLevelEnum = RiskLevelEnum.find(riskLevelId);
            if(null != riskLevelEnum){
                resources.setRiskLevelCode(riskLevelEnum.getCode());
                resources.setRiskLevelName(riskLevelEnum.getName());
            }
        }
        riskZoningManageRepository.save(riskZoningManage);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            riskZoningManageRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<RiskZoningManageDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (RiskZoningManageDto riskZoningManage : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("创建时间", riskZoningManage.getCreateTime());
            map.put("更新时间", riskZoningManage.getUpdateTime());
            map.put("创建者", riskZoningManage.getCreateBy());
            map.put("更新者", riskZoningManage.getUpdateBy());
            map.put("分区名称", riskZoningManage.getZoningName());
            map.put("部门负责人主键", riskZoningManage.getDepManagerId());
            map.put("部门负责人名称", riskZoningManage.getDepManageName());
            map.put("关联区域主键", riskZoningManage.getRelAreaId());
            map.put("关联区域名称", riskZoningManage.getRelAreaName());
            map.put("风险等级", riskZoningManage.getRiskLevelName());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }
}